package org.example.netty.gRPCTest;

import com.shengsiyuan.proto.*;
import io.grpc.stub.StreamObserver;

import java.util.UUID;

// gRPC服务实现类
public class GrpcServiceImpl extends StudentServiceGrpc.StudentServiceImplBase {
    // 重写gRPC服务方法
    /*
     * 请求参数 request：客户端传递的请求数据,StreamObserver是服务端向客户端发送响应数据的对象, StreamObserver是gRPC提供的一个接口
     * 响应参数 responseObserver：服务端向客户端发送响应数据,需要实现onNext、onError和onCompleted方法,
     *  onNext用于向客户端发送响应数据  onNext方法可以调用多次向客户端发送响应数据
     *  onError用于处理异常信息 (onError方法在gRPC中是可选的)
     *  onCompleted用于结束响应数据 (onCompleted方法在gRPC中是可选的)
     */
    //Simple RPC（简单RPC）
    @Override
    public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
        String username = request.getUsername();
        System.out.println("gRPC服务端接收到请求：" + username);
        // 构造响应数据
        MyResponse response = MyResponse.newBuilder().setRealname("target").build();
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
    //Server-side streaming RPC（服务端流式RPC）
    @Override
    public void getStudentsByAge(StudentRequestAge request, StreamObserver<StudentResponse> responseObserver) {
        System.out.println("gRPC服务端接收到请求");
        // 构造响应数据
        responseObserver.onNext(StudentResponse.newBuilder().setName("target")
                .setAge(19)
                .setCity("靶机监控")
                .build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("target1")
                .setAge(20)
                .setCity("靶机监控1")
                .build());
        responseObserver.onNext(StudentResponse.newBuilder().setName("target2")
                .setAge(21)
                .setCity("靶机监控2")
                .build());
        // 结束响应数据
        responseObserver.onCompleted();
    }
//    Client-side streaming RPC(客户端流式RPC)
    @Override
    public StreamObserver<StudentRequestAge> getStudentsByAges(StreamObserver<StudentResponseList> responseObserver) {
        // 返回StreamObserver对象,用于接收客户端的请求数据,
        // StreamObserver是gRPC提供的一个接口,需要实现onNext、onError和onCompleted方法
        return new StreamObserver<StudentRequestAge>() {
            // 接收客户端的请求数据,onNext方法可以调用多次,一次次接收客户端的请求数据
            @Override
            public void onNext(StudentRequestAge value) {
                System.out.println("gRPC服务端接收到请求: " + value.getAge());
            }

            @Override
            public void onError(Throwable throwable) {

            }
            // 结束接收客户端的请求数据,onCompleted方法在gRPC中是可选的
            // 在gRPC中onCompleted方法表示客户端已经结束发送请求数据
            @Override
            public void onCompleted() {
                // 构造响应数据
                StudentResponse studentResponse=StudentResponse.newBuilder().setName("张三").setAge(20).setCity("西安").build();
                StudentResponse studentResponse2=StudentResponse.newBuilder().setName("李四").setAge(30).setCity("广州").build();
                StudentResponseList studentResponseList =StudentResponseList.newBuilder()
                        .addStudent(studentResponse)
                        .addStudent(studentResponse2)
                        .build();
                responseObserver.onNext(studentResponseList);
                // 结束响应数据
                responseObserver.onCompleted();
            }
        };
    }
    //Bidirectional streaming RPC(双向流式RPC)
    @Override
    public StreamObserver<StreamRequest> biTalk(StreamObserver<StreamResponse> responseObserver) {
        // 返回StreamObserver对象,用于接收客户端的请求数据
        return new StreamObserver<StreamRequest>() {
            @Override
            public void onNext(StreamRequest value) {
                System.out.println("gRPC服务端接收到请求: " + value);
                // 构造响应数据
                responseObserver.onNext(StreamResponse.newBuilder()
                        .setResponseInfo(UUID.randomUUID().toString())
                        .build());
            }

            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onCompleted() {
                // 结束响应数据
                responseObserver.onCompleted();
            }
        };
    }
}
